package cn.weforward.task.weforward;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.weforward.common.ResultPage;
import cn.weforward.common.util.StringUtil;
import cn.weforward.common.util.TransResultPage;
import cn.weforward.data.log.BusinessLog;
import cn.weforward.framework.ApiException;
import cn.weforward.framework.WeforwardMethod;
import cn.weforward.framework.WeforwardMethods;
import cn.weforward.framework.doc.DocMethods;
import cn.weforward.framework.exception.ForwardException;
import cn.weforward.framework.util.ValidateUtil;
import cn.weforward.protocol.client.util.IdBean;
import cn.weforward.protocol.doc.annotation.DocAttribute;
import cn.weforward.protocol.doc.annotation.DocMethod;
import cn.weforward.protocol.doc.annotation.DocParameter;
import cn.weforward.protocol.support.datatype.FriendlyObject;
import cn.weforward.task.Tag;
import cn.weforward.task.Task;
import cn.weforward.task.TaskService;
import cn.weforward.task.impl.SimpleTask;
import cn.weforward.task.weforward.view.BugsAnalyzeView;
import cn.weforward.task.weforward.view.LogView;
import cn.weforward.task.weforward.view.LogsParams;
import cn.weforward.task.weforward.view.SearchTaskParam;
import cn.weforward.task.weforward.view.SimpleTaskView;
import cn.weforward.task.weforward.view.TaskParams;
import cn.weforward.task.weforward.view.TaskView;
import cn.weforward.task.weforward.view.UndateTaskHandlerssParam;
import cn.weforward.task.weforward.view.UpdateTaskParam;

/**
 * 任务接口
 * @author 朱海斌
 *
 */
@DocMethods(index = 100)
@WeforwardMethods
public class TaskMethods{
	@Resource
	TaskService m_Service;
	
	final static Logger _Logger = LoggerFactory.getLogger(TaskMethods.class);
	
	@WeforwardMethod
	@DocMethod(description = "创建一个任务(子任务/父任务)" , index = 1)
	public TaskView create(TaskParams params) throws ApiException{
		String title = params.getTitle();
		String content = params.getContent();
		String fatherTaskId = params.getFatherTaskId();
		String manager = params.getManager();
		List<String> handlers = params.getHandlers();
		String tag = params.getTag();
		int priority = params.getPriority();
		Date expectedStartTime = params.getExpectedStartTime();
		Date expectedEndTime = params.getExpectedEndTime();
		
		ValidateUtil.isEmpty(title, "标题不能为空");
		ValidateUtil.isEmpty(content, "任务内容不能为空");
		ValidateUtil.isEmpty(manager, "负责人不能为空");

		ValidateUtil.isEmpty(priority, "优先级不能为空");
		ValidateUtil.isEmpty(expectedStartTime, "期望开始时间不能为空");
		ValidateUtil.isEmpty(expectedEndTime, "期望结束时间不能为空");
		
		//如果用户希望设置fatherTaskId
		if(!"".equals(fatherTaskId)) {
			//先判断父任务id是否存在，如果不存在，返回报错信息
			ValidateUtil.isNull(m_Service.getTask(fatherTaskId), "该父任务id不存在");
		}
		//如果用户希望设置标签id
		if(!"".equals(tag)) {
			//先判断tag id是否存在，如果不存在，返回报错信息
			ValidateUtil.isNull(m_Service.getTag(tag), "该标签id不存在");
		}
		//如果优先级不在此范围内，默认给他一个1
		if(priority<1 || priority>4) {
			priority = 1;
		}
		Task task = m_Service.createTask(title, content, fatherTaskId, manager, handlers, tag, priority, expectedStartTime, expectedEndTime);
		
		return TaskView.valueOf(task);
	}
	
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", type = String.class, necessary = true, description = "任务id"))
	@DocMethod(description = "获取任务" , index = 2)
	public TaskView get(FriendlyObject params) throws ApiException{
		return TaskView.valueOf(check(m_Service.getTask(params.getString("id"))));
	}

	
	@WeforwardMethod
	@DocMethod(description = "修改任务" , index = 3)
	public TaskView update(UpdateTaskParam params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该任务id不存在");
		String tag = params.getTag();
		
		if(!StringUtil.isEmpty(tag) && null != tag) {
			//判断传进来的标签id是否存在
			ValidateUtil.isNull(m_Service.getTag(tag), "该标签id不存在");
			task.setTag(tag);
		}
		
		String title = params.getTitle();
		if(!StringUtil.isEmpty(title)) {
			task.setTitle(title);
		}
		String content = params.getContent();
		if(!StringUtil.isEmpty(content)) {
			task.setContent(content);
		}
		int priority = params.getPriority();
		task.setPriority(priority);
		
		String manager = params.getManager();
		if(!StringUtil.isEmpty(manager)) {
			task.setManager(manager);
		}
		List<String> handlers = params.getHandlers();
		if(null != handlers && handlers.size()>=0) {
			task.setHandlers(handlers);
		}
		String follower = params.getFollower();
		if(!StringUtil.isEmpty(follower)) {
			task.addFollower(follower);
		}
		
		Date expectedStartTime = params.getExpectedStartTime();
		Date expectedEndTime = params.getExpectedEndTime();
		
		if(null != expectedStartTime) {
			task.setExpectedStartTime(expectedStartTime);
		}
		
		if(null != expectedEndTime) {
			task.setExpectedEndTime(expectedEndTime);
		}
		
		Date endTime = params.getEndTime();
		if(null != endTime) {
			//如果用户想要设置结束时间
			if(task.getState().id >= 8 && task.getState().id < 10) {
				//如果当前任务已经上线，便可以设置结束时间
				task.setEndTime(endTime);
			}else {
				ValidateUtil.isZero(0, "该任务还未上线或还未拒绝，不能设置结束时间");
			}
		}
		
		return TaskView.valueOf(task);
	}
	
	@WeforwardMethod
	@DocMethod(description = "添加处理人" , index = 4)
	public TaskView addHandlers(UndateTaskHandlerssParam params) throws ApiException {
		ValidateUtil.isEmpty(params.getId(), "请输入任务id");
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该任务id为空");
		List<String> handlers = params.getHandlers();
		ValidateUtil.isEmpty(handlers, "请输入要添加的处理人");
		
		//判断是否有重复
		Set set = new HashSet<>(handlers);
		boolean res = set.size()<handlers.size();
		ValidateUtil.checkIllegalArgument(res, "添加的处理人中有重复出现的名字");
		
		List<String> handlers2 = handlers;
		
		task.addHandlers(handlers2);
		return TaskView.valueOf(task);
	}
	
	@WeforwardMethod
	@DocMethod(description = "移除处理人" , index = 4)
	public TaskView removeHandlers(UndateTaskHandlerssParam params) throws ApiException {
		ValidateUtil.isEmpty(params.getId(), "请输入任务id");
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该任务id为空");
		List<String> handlers = params.getHandlers();
		ValidateUtil.isEmpty(handlers, "请输入要移除的处理人");
		
		//判断是否有重复
		Set set = new HashSet<>(handlers);
		boolean res = set.size()<handlers.size();
		ValidateUtil.checkIllegalArgument(res, "移除的处理人中有重复出现的名字");
		
		task.removeHandlers(handlers);
		return TaskView.valueOf(task);
	}
	
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "option", type = Integer.class, necessary = true, description = "option>=7 完成  option<7 未完成"),
		@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
		@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "搜索任务（完成/未完成）",index = 4)
	public ResultPage<SimpleTaskView> search(SearchTaskParam params) throws ApiException {
		
		int want = params.getOption();
		ResultPage<SimpleTask> rp = null;
		if(want<7) {
			//代表用户要查询未完成的任务
			rp = m_Service.searchUnfinishedTasks(want);
		}else {
			//代表用户要查询已完成的任务
			rp = m_Service.searchFinishedTasks(want);
		}
		
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp) {
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
			
		};
	}
	
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "option", type = Integer.class, necessary = true, description = "option:0/1 未完成/已完成"),
					@DocAttribute(name = "handlers", type = List.class, necessary = true, description = "一个或多个处理人的名字"),
					@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
					@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "搜索指定处理人的任务(option:0/1 未完成/已完成)", index = 5)
	public ResultPage<SimpleTaskView> searchByHandlers(SearchTaskParam params) throws ApiException{
		ResultPage<SimpleTask> rp = null;
		if(params.getOption() == 0) {
			//如果用户想要查找指定处理人的未完成的任务
			rp = m_Service.findUnfinishedTaskByHandler(params.getHandlers());
		}
		
		if(params.getOption() == 1) {
			//如果用户想要查找指定处理人的已完成的任务
			rp = m_Service.findFinishedTaskByHandler(params.getHandlers());
		}
		
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
		
	}
	
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "option", type = Integer.class, necessary = true, description = "option:0/1 未完成/已完成"),
					@DocAttribute(name = "follower", type = String.class, necessary = true, description = "跟进人姓名"),
					@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
					@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "搜索指定最新跟进人的任务(option:0/1 未完成/已完成)", index = 6)
	public ResultPage<SimpleTaskView> searchByFollower(SearchTaskParam params) throws ApiException{
		ResultPage<SimpleTask> rp = null;
		if(params.getOption() == 0) {
			//如果用户想要查找指定跟进人的未完成的任务
			rp = m_Service.findUnfinishedTaskByFollower(params.getFollower());
		}
		if(params.getOption() == 1) {
			//如果用户想要查找指定跟进人的已完成的任务
			rp = m_Service.findFinishedTaskByFollower(params.getFollower());
		}
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
	}
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "option", type = Integer.class, necessary = true, description = "option:0/1 未完成/已完成"),
					@DocAttribute(name = "manager", type = String.class, necessary = true, description = "负责人姓名"),
					@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
					@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "搜索指定负责人的任务(option:0/1 未完成/已完成)", index = 7)
	public ResultPage<SimpleTaskView> searchByManager(SearchTaskParam params) throws ApiException{
		ResultPage<SimpleTask> rp = null;
		if(params.getOption() == 0) {
			//如果用户想要查找指定负责人的未完成的任务
			rp = m_Service.findUnfinishedTaskByManager(params.getManager());
		}
		if(params.getOption() == 1) {
			//如果用户想要查找指定负责人的已完成的任务
			rp = m_Service.findFinishedTaskByManager(params.getManager());
		}
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
	}
	
	private Task check(Task task) {
		if (null == task) {
			return null;
		}

		return task;
	}

	/**
	 * 获取日志
	 */
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "id", type = Integer.class, necessary = true, description = "任务id"),
		@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
		@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "获取任务日志", index = 8)
	public ResultPage<LogView> logs(LogsParams params) throws ApiException {
		String id = params.getId();
		ValidateUtil.isEmpty(id, "id不能为空");
		Task task = m_Service.getTask(id);
		
		ForwardException.forwardToIfNeed(task);
		return new TransResultPage<LogView, BusinessLog>(task.getLogs()) {
			@Override
			protected LogView trans(BusinessLog src) {
				return LogView.valueOf(src);
			}
		};
	}
	
	

	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为评估中", index = 9)
	public TaskView turnAssess(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.assess();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为规划中", index = 10)
	public TaskView turnPlan(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.plan();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为待开发", index = 11)
	public TaskView turnGonnaDev(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.gonnaDev();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为开发中", index = 12)
	public TaskView turnDev(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.dev();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为待测试",index = 13)
	public TaskView turnGonnaTest(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.gonnaTest();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为测试中",index = 14)
	public TaskView turnTest(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.test();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为测试通过",index = 15)
	public TaskView turnPassTest(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.passTest();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为已上线",index = 16)
	public TaskView turnUp(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.up();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为已拒绝",index = 17)
	public TaskView turnRefuse(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.refuse();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "状态扭转为挂起",index = 18)
	public TaskView turnHangUp(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		task = check(task);

		task.hangUp();
		return TaskView.valueOf(task);
	}
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "id", necessary = true,type = String.class, description = "父任务id"),
				@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
				@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "根据父任务id获取子任务",index = 19)
	public ResultPage<SimpleTaskView> getSonTasks(IdBean params) throws ApiException{
		ValidateUtil.isEmpty(params.getId(), "请输入父任务id");
		Task fatherTask = m_Service.getTask(params.getId());
		ValidateUtil.isNull(fatherTask, "该父任务id为空");
		ResultPage<SimpleTask> rp = fatherTask.getSonTasks();
		
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
	}
	
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "id", necessary = true,type = String.class, description = "标签id"),
		@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
		@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "根据标签id获取父任务",index = 19)
	public ResultPage<SimpleTaskView> getTasksByTag(IdBean params) throws ApiException{
		Tag tag = m_Service.getTag(params.getId());
		ValidateUtil.isNull(tag, "该标签id不存在");
		ResultPage<SimpleTask> rp = tag.getTasks(params.getId());
		return new TransResultPage<SimpleTaskView, SimpleTask>(rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
	}
	
	@WeforwardMethod
	@DocParameter({@DocAttribute(name = "page", type = Integer.class, necessary = false, description = "第几页"),
					@DocAttribute(name = "pageSize", type = Integer.class, necessary = false, description = "一页数据大小")})
	@DocMethod(description = "获取所有父任务",index = 20)
	public ResultPage<SimpleTaskView> getAllTasks()throws ApiException{
		ResultPage<SimpleTask> rp = m_Service.searchAllTasks();
		
		return new TransResultPage<SimpleTaskView, SimpleTask>((ResultPage<SimpleTask>) rp){
			@Override
			protected SimpleTaskView trans(SimpleTask src) {
				return SimpleTaskView.valueOf(src);
			}
		};
	}
	
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "分析指定任务下的bugs",index = 21)
	public BugsAnalyzeView analyzeBugs(IdBean params) throws ApiException{
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该id的任务不存在");
		HashMap<String, Integer> map = task.analyzeBugs();
		
		return new BugsAnalyzeView(map);
	}
	
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "清空指定任务下的预计结束时间",index = 22)
	public TaskView emptyExpectedEndTime(IdBean params) throws ApiException {
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该id的任务不存在");
		task.setExpectedEndTime(null);
		return TaskView.valueOf(task);
	}
	
	@WeforwardMethod
	@DocParameter(@DocAttribute(name = "id", necessary = true,type = String.class, description = "任务id"))
	@DocMethod(description = "清空指定任务下的预计开始时间",index = 23)
	public TaskView emptyExpectedStartTime(IdBean params) throws ApiException {
		Task task = m_Service.getTask(params.getId());
		ValidateUtil.isNull(task, "该id的任务不存在");
		task.setExpectedStartTime(null);
		return TaskView.valueOf(task);
	}
}
